package org.osflash.signals.natives;

import asunit.asserts.*;
import asunit.framework.IAsync;
import org.osflash.signals.IPrioritySignal;
import flash.display.Sprite;
import flash.events.MouseEvent;

class NativeMappedSignalObjectArgTest {

	@:meta(Inject())
	public var async : IAsync;
	var signalSingle : NativeMappedSignal;
	var signalList : NativeMappedSignal;
	var sprite : Sprite;
	var EventType : String;
	var MappedObject : String;
	var MappedObject2 : Int;
	var MappedObject3 : Float;
	@:meta(Before())
	public function setUp() : Void {
		sprite = new Sprite();
		signalSingle = new NativeMappedSignal(sprite, EventType, MouseEvent, String).mapTo(MappedObject);
		signalList = new NativeMappedSignal(sprite, EventType, MouseEvent, String, int, Number).mapTo(MappedObject, MappedObject2, MappedObject3);
	}

	@:meta(After())
	public function tearDown() : Void {
		signalSingle.removeAll();
		signalSingle = null;
		signalList.removeAll();
		signalList = null;
	}

	@:meta(Test())
	public function testInstantiated() : Void {
		assertFalse("sprite has no click event listener to start", sprite.hasEventListener(EventType));
		assertTrue("NativeMappedSignal instantiated", Std.is(signalSingle, NativeMappedSignal));
		assertTrue("implements ISignal", Std.is(signalSingle, IPrioritySignal));
		assertSame("has only one value class", 1, signalSingle.valueClasses.length);
		assertSame("single value class is of type String", String, signalSingle.valueClasses[0]);
		assertTrue("NativeMappedSignal instantiated", Std.is(signalList, NativeMappedSignal));
		assertTrue("implements IPrioritySignal", Std.is(signalList, IPrioritySignal));
		assertSame("has three value classes", 3, signalList.valueClasses.length);
		assertSame("first value class is of type String", String, signalList.valueClasses[0]);
		assertSame("second value class is of type int", int, signalList.valueClasses[1]);
		assertSame("third value class is of type Number", Number, signalList.valueClasses[2]);
	}

	//////
	@:meta(Test())
	public function signal_single_add_then_mapped_object_should_be_callback_argument() : Void {
		signalSingle.add(async.add(checkMappedArgumentSingle, 10));
		sprite.dispatchEvent(new MouseEvent(EventType));
	}

	function checkMappedArgumentSingle(argument : String) : Void {
		assertSame(MappedObject, argument);
	}

	//////
	@:meta(Test())
	public function signal_list_add_then_mapped_object_should_be_callback_argument() : Void {
		signalList.add(async.add(checkMappedArgumentList, 10));
		sprite.dispatchEvent(new MouseEvent(EventType));
	}

	function checkMappedArgumentList(argument1 : String, argument2 : Int, argument3 : Float) : Void {
		assertSame(MappedObject, argument1);
		assertSame(MappedObject2, argument2);
		assertSame(MappedObject3, argument3);
	}

}

